#ifndef _MASTER_H_
#define _MASTER_H_
#include <pthread.h>
#include "dss_common.h"
//master state
enum {
	PREPARE = 0,
	ACTIVE,
	EXIT,
};
//chunkserver state
enum {
	DOWN = 0,
	UP,
};


struct Master;
struct ChunkServer;
struct ChunkOp;
struct HeartbeatInfo;

struct Master {
	uint64_t id;
	char *conf;
	char *uri;
	uint32_t heartbeat_interval;
	uint32_t state; // 0: PREPARE; 1: ACTIVE; 2: EXIT
	pthread_t heartbeat_th;
	uint64_t last_active;
	//map<uint64_t, struct ChunkServer *> 	chunkservers;
	//map<uint64_t, struct HeartbeatInfo *> heartbeatmap;
	uint32_t cs_num;
	struct ChunkServer **chunkservers;
	struct HeartbeatInfo **heartbeatmap;
	struct rpc *rpc_client;
	struct rpc *rpc_server;
	uint32_t cur_id;
	uint64_t cur_cs;

};

struct ChunkServer {
	uint64_t id;
	char *uri;
	int session_id;
	//TODO need lock ??
	uint32_t state; //0: DOWN, 1: UP
	uint32_t cluster_total;	//the number of total clusters in blobstore
	uint32_t cluster_free;	//the number of free clusters in blobstore
	uint32_t cluster_size;	//the size of a cluster, usually 1MB
	uint32_t io_unit_size;	//read or write minimum size, usually 4KB, need or not??

};

struct ChunkOp {
	struct rpc_execution *rpc_ex;
	struct dss_msg *dss_request;
	struct dss_msg *dss_response;
	uint64_t total_response;
	uint64_t cur_response;

};

struct HeartbeatInfo {
	uint64_t chunkserver;
	//TODO need lock??
	uint64_t last_tid;
	uint64_t last_heartbeat;

};

int parse_master_conf(char *conf);
/* rpc service */
void m_chunk_op_service(void *arg1, void *arg2, void *arg3);
void m_sys_status_service(void *arg1, void *arg2, void *arg3);
void m_heartbeat_service(void *arg1, void *arg2, void *arg3);
void m_handle_op_create(struct ChunkOp *op);
void m_handle_op_list(struct ChunkOp *op);
void master_create_cb(void *arg1, void *arg2, void *ctx);
void master_list_cb(void *arg1, void *arg2, void *ctx);
int chunkserver_select();

void master_prepare();
void master_exit();


#endif // !_MASTER_H_
